Skip to content

[BUGFIX beta] Fix 'on' modifier error message regression#21091

Merged
NullVoxPopuli merged 1 commit intoemberjs:mainfrom
crazylogic03:fix/on-modifier-error-message
Feb 16, 2026
Merged

[BUGFIX beta] Fix 'on' modifier error message regression#21091
NullVoxPopuli merged 1 commit intoemberjs:mainfrom
crazylogic03:fix/on-modifier-error-message

Conversation

@crazylogic03
Copy link
Contributor

@crazylogic03 crazylogic03 commented Feb 15, 2026

This PR fixes a regression where the helpful error message for the 'on' modifier was lost when the callback is undefined or not a function.

It adds an explicit runtime check in DEBUG mode to ensure the callback is a function, and includes a reproduction test case to verify the fix.

Copy link
Contributor Author

@crazylogic03 crazylogic03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have implemented a fix to restore the helpful error message when the

on
modifier is used without a function callback.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 15, 2026

Estimated Asset Sizes

Diff

--- main/out.txt	2026-02-13 16:38:38.000000000 +0000
+++ pr/./pr-22046609923/out.txt	2026-02-16 01:02:54.000000000 +0000
@@ -1,16 +1,16 @@
 ╔═══════╤═══════════╤═══════════╗
 ║       │ Min       │ Gzip      ║
 ╟───────┼───────────┼───────────╢
-║ Total │ 352.02 KB │ 203.77 KB ║
+║ Total │ 352.02 KB │ 203.83 KB ║
 ╚═══════╧═══════════╧═══════════╝
 
 ╔══════════════════════╤═══════════╤═══════════╗
 ║ @ember/*             │ Min       │ Gzip      ║
 ╟──────────────────────┼───────────┼───────────╢
-║ Total                │ 313.42 KB │ 181.95 KB ║
+║ Total                │ 313.42 KB │ 181.89 KB ║
 ╟──────────────────────┼───────────┼───────────╢
-║ -internals           │ 36.65 KB  │ 26.23 KB  ║
-║ application          │ 13.23 KB  │ 8.09 KB   ║
+║ -internals           │ 36.65 KB  │ 26.22 KB  ║
+║ application          │ 13.23 KB  │ 8.05 KB   ║
 ║ array                │ 13.01 KB  │ 7.46 KB   ║
 ║ canary-features      │ 304 B     │ 389 B     ║
 ║ component            │ 2.05 KB   │ 1.64 KB   ║
@@ -19,16 +19,16 @@
 ║ deprecated-features  │ 31 B      │ 77 B      ║
 ║ destroyable          │ 561 B     │ 383 B     ║
 ║ enumerable           │ 259 B     │ 387 B     ║
-║ helper               │ 1.08 KB   │ 803 B     ║
+║ helper               │ 1.08 KB   │ 811 B     ║
 ║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
-║ modifier             │ 1.22 KB   │ 966 B     ║
+║ modifier             │ 1.22 KB   │ 965 B     ║
 ║ object               │ 35.94 KB  │ 22.16 KB  ║
 ║ owner                │ 159 B     │ 178 B     ║
-║ renderer             │ 630 B     │ 492 B     ║
-║ routing              │ 59.33 KB  │ 34.13 KB  ║
+║ renderer             │ 630 B     │ 487 B     ║
+║ routing              │ 59.33 KB  │ 34.1 KB   ║
 ║ runloop              │ 2.36 KB   │ 1.5 KB    ║
 ║ service              │ 1 KB      │ 845 B     ║
-║ template             │ 654 B     │ 519 B     ║
+║ template             │ 654 B     │ 541 B     ║
 ║ template-compilation │ 429 B     │ 366 B     ║
 ║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
 ║ template-factory     │ 370 B     │ 374 B     ║
@@ -40,19 +40,19 @@
 ╔═════════════════╤══════════╤══════════╗
 ║ @glimmer/*      │ Min      │ Gzip     ║
 ╟─────────────────┼──────────┼──────────╢
-║ Total           │ 38.6 KB  │ 21.82 KB ║
+║ Total           │ 38.6 KB  │ 21.94 KB ║
 ╟─────────────────┼──────────┼──────────╢
 ║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
 ║ encoder         │ 81 B     │ 171 B    ║
 ║ env             │ 38 B     │ 87 B     ║
 ║ global-context  │ 886 B    │ 545 B    ║
 ║ manager         │ 977 B    │ 608 B    ║
-║ node            │ 175 B    │ 245 B    ║
+║ node            │ 175 B    │ 260 B    ║
 ║ opcode-compiler │ 1.11 KB  │ 894 B    ║
 ║ owner           │ 159 B    │ 202 B    ║
 ║ program         │ 252 B    │ 301 B    ║
 ║ reference       │ 548 B    │ 531 B    ║
-║ runtime         │ 10.32 KB │ 5.22 KB  ║
+║ runtime         │ 10.32 KB │ 5.32 KB  ║
 ║ tracking        │ 1.34 KB  │ 1.16 KB  ║
 ║ util            │ 1.94 KB  │ 1.68 KB  ║
 ║ validator       │ 15.75 KB │ 6.96 KB  ║

Details

This PRmain
╔═══════╤═══════════╤═══════════╗
║       │ Min       │ Gzip      ║
╟───────┼───────────┼───────────╢
║ Total │ 352.02 KB │ 203.83 KB ║
╚═══════╧═══════════╧═══════════╝

╔══════════════════════╤═══════════╤═══════════╗
║ @ember/*             │ Min       │ Gzip      ║
╟──────────────────────┼───────────┼───────────╢
║ Total                │ 313.42 KB │ 181.89 KB ║
╟──────────────────────┼───────────┼───────────╢
║ -internals           │ 36.65 KB  │ 26.22 KB  ║
║ application          │ 13.23 KB  │ 8.05 KB   ║
║ array                │ 13.01 KB  │ 7.46 KB   ║
║ canary-features      │ 304 B     │ 389 B     ║
║ component            │ 2.05 KB   │ 1.64 KB   ║
║ controller           │ 1.96 KB   │ 1.41 KB   ║
║ debug                │ 11.69 KB  │ 8.12 KB   ║
║ deprecated-features  │ 31 B      │ 77 B      ║
║ destroyable          │ 561 B     │ 383 B     ║
║ enumerable           │ 259 B     │ 387 B     ║
║ helper               │ 1.08 KB   │ 811 B     ║
║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
║ modifier             │ 1.22 KB   │ 965 B     ║
║ object               │ 35.94 KB  │ 22.16 KB  ║
║ owner                │ 159 B     │ 178 B     ║
║ renderer             │ 630 B     │ 487 B     ║
║ routing              │ 59.33 KB  │ 34.1 KB   ║
║ runloop              │ 2.36 KB   │ 1.5 KB    ║
║ service              │ 1 KB      │ 845 B     ║
║ template             │ 654 B     │ 541 B     ║
║ template-compilation │ 429 B     │ 366 B     ║
║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
║ template-factory     │ 370 B     │ 374 B     ║
║ test                 │ 923 B     │ 627 B     ║
║ utils                │ 4.11 KB   │ 3.6 KB    ║
║ version              │ 55 B      │ 131 B     ║
╚══════════════════════╧═══════════╧═══════════╝

╔═════════════════╤══════════╤══════════╗
║ @glimmer/*      │ Min      │ Gzip     ║
╟─────────────────┼──────────┼──────────╢
║ Total           │ 38.6 KB  │ 21.94 KB ║
╟─────────────────┼──────────┼──────────╢
║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
║ encoder         │ 81 B     │ 171 B    ║
║ env             │ 38 B     │ 87 B     ║
║ global-context  │ 886 B    │ 545 B    ║
║ manager         │ 977 B    │ 608 B    ║
║ node            │ 175 B    │ 260 B    ║
║ opcode-compiler │ 1.11 KB  │ 894 B    ║
║ owner           │ 159 B    │ 202 B    ║
║ program         │ 252 B    │ 301 B    ║
║ reference       │ 548 B    │ 531 B    ║
║ runtime         │ 10.32 KB │ 5.32 KB  ║
║ tracking        │ 1.34 KB  │ 1.16 KB  ║
║ util            │ 1.94 KB  │ 1.68 KB  ║
║ validator       │ 15.75 KB │ 6.96 KB  ║
║ vm              │ 495 B    │ 569 B    ║
║ wire-format     │ 1.84 KB  │ 1.35 KB  ║
╚═════════════════╧══════════╧══════════╝
╔═══════╤═══════════╤═══════════╗
║       │ Min       │ Gzip      ║
╟───────┼───────────┼───────────╢
║ Total │ 352.02 KB │ 203.77 KB ║
╚═══════╧═══════════╧═══════════╝

╔══════════════════════╤═══════════╤═══════════╗
║ @ember/*             │ Min       │ Gzip      ║
╟──────────────────────┼───────────┼───────────╢
║ Total                │ 313.42 KB │ 181.95 KB ║
╟──────────────────────┼───────────┼───────────╢
║ -internals           │ 36.65 KB  │ 26.23 KB  ║
║ application          │ 13.23 KB  │ 8.09 KB   ║
║ array                │ 13.01 KB  │ 7.46 KB   ║
║ canary-features      │ 304 B     │ 389 B     ║
║ component            │ 2.05 KB   │ 1.64 KB   ║
║ controller           │ 1.96 KB   │ 1.41 KB   ║
║ debug                │ 11.69 KB  │ 8.12 KB   ║
║ deprecated-features  │ 31 B      │ 77 B      ║
║ destroyable          │ 561 B     │ 383 B     ║
║ enumerable           │ 259 B     │ 387 B     ║
║ helper               │ 1.08 KB   │ 803 B     ║
║ instrumentation      │ 2.43 KB   │ 1.79 KB   ║
║ modifier             │ 1.22 KB   │ 966 B     ║
║ object               │ 35.94 KB  │ 22.16 KB  ║
║ owner                │ 159 B     │ 178 B     ║
║ renderer             │ 630 B     │ 492 B     ║
║ routing              │ 59.33 KB  │ 34.13 KB  ║
║ runloop              │ 2.36 KB   │ 1.5 KB    ║
║ service              │ 1 KB      │ 845 B     ║
║ template             │ 654 B     │ 519 B     ║
║ template-compilation │ 429 B     │ 366 B     ║
║ template-compiler    │ 123.08 KB │ 59.45 KB  ║
║ template-factory     │ 370 B     │ 374 B     ║
║ test                 │ 923 B     │ 627 B     ║
║ utils                │ 4.11 KB   │ 3.6 KB    ║
║ version              │ 55 B      │ 131 B     ║
╚══════════════════════╧═══════════╧═══════════╝

╔═════════════════╤══════════╤══════════╗
║ @glimmer/*      │ Min      │ Gzip     ║
╟─────────────────┼──────────┼──────────╢
║ Total           │ 38.6 KB  │ 21.82 KB ║
╟─────────────────┼──────────┼──────────╢
║ destroyable     │ 2.77 KB  │ 1.39 KB  ║
║ encoder         │ 81 B     │ 171 B    ║
║ env             │ 38 B     │ 87 B     ║
║ global-context  │ 886 B    │ 545 B    ║
║ manager         │ 977 B    │ 608 B    ║
║ node            │ 175 B    │ 245 B    ║
║ opcode-compiler │ 1.11 KB  │ 894 B    ║
║ owner           │ 159 B    │ 202 B    ║
║ program         │ 252 B    │ 301 B    ║
║ reference       │ 548 B    │ 531 B    ║
║ runtime         │ 10.32 KB │ 5.22 KB  ║
║ tracking        │ 1.34 KB  │ 1.16 KB  ║
║ util            │ 1.94 KB  │ 1.68 KB  ║
║ validator       │ 15.75 KB │ 6.96 KB  ║
║ vm              │ 495 B    │ 569 B    ║
║ wire-format     │ 1.84 KB  │ 1.35 KB  ║
╚═════════════════╧══════════╧══════════╝

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 looks like tests don't pass

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 can you show a before and after of what you see in the browser after making this change? (for the changelog, it would be helpful to know what the specific problem being solved is) tyty!

@crazylogic03
Copy link
Contributor Author

@NullVoxPopuli
Specific Problem:
In recent versions (since 5.12), passing a non-function (like undefined or null) to the on modifier resulted in unhelpful or generic errors, making it hard to track down where the invalid value came from.

Before:
The validation was either missing or generic assertion failures that didn't help pinpoint the issue.

After:
The modifier now explicitly checks the callback type in DEBUG mode and throws a descriptive error including the type received and the debug label of the argument.
Example Error:
You must pass a function as the second argument to the 'on' modifier; you passed undefined. While rendering: ...

@NullVoxPopuli
Copy link
Contributor

@crazylogic03 legit thanks for looking in to this! new error phrasing looks good. what was the old error?

@NullVoxPopuli
Copy link
Contributor

Looks like on 6.10, we get "Cannot access bind of undefined" (not good lol)

@crazylogic03
Copy link
Contributor Author

@NullVoxPopuli Yep, exactly!
The old error Cannot read properties of undefined (reading 'bind') happened because we were trying to .bind() the callback for debug context before actually verifying it was a function.
This PR adds an explicit check before that point, so instead of crashing with a native JS error, we now get a helpful Ember assertion telling you exactly what argument was passed (e.g. undefined or null) and where.

@crazylogic03
Copy link
Contributor Author

@NullVoxPopuli Can You Review merge this PR and All the Checks have passed

@crazylogic03
Copy link
Contributor Author

Thanks for the review @NullVoxPopuli! I'm glad we could get this fixed.

@crazylogic03
Copy link
Contributor Author

@kategengler Can You Review merge this PR and All the Checks have passed 🙂

This restores the helpful error message when the 'on' modifier is used without a function callback, which was lost in a recent refactor.
@NullVoxPopuli NullVoxPopuli force-pushed the fix/on-modifier-error-message branch from 790f2ce to 5977946 Compare February 16, 2026 01:01
@NullVoxPopuli
Copy link
Contributor

thank you @crazylogic03 I hope you'll find more places to improve the DX in ember <3

@NullVoxPopuli NullVoxPopuli merged commit 09af24c into emberjs:main Feb 16, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants